//
// Created by tang on 2022/1/11.
//

#include "redmine_tools_view.hpp"
#include "gui/dialog_names.h"
#include "gui/ui_component.hpp"
#include "imgui/imgui.h"
#include "imgui/imgui_stdlib.h"
#include "imgui/IconsFontAwesome4.h"
#include "app/app_base.hpp"
#include "sql/types.hpp"
#include "integrations/redmine/redmine_apis.hpp"
#include <shared_mutex>
#include <mutex>

#include "gui/controls/custom_controls.hpp"
#include "event/events.hpp"

struct RedMineData
{
    bool reload_activities = true;
    bool reload_issues = true;

    std::vector<RedMineActivity> activities;
    std::vector<RedMineIssue> imported_issues;

    // mgm data
    bool dialog_first_frame = true;
    std::string search_key_word;
    bool filter_assigned_to_me{ true };
    bool filter_open_only{ true };
    int search_type = RedMine::SFT_SUBJECT;
    int page{ 0 };
    int total_result{ 0 };
    const int page_size{ 20 };
    std::vector<RedMineIssue> result_issues;
    std::shared_mutex result_rw_lock;
    bool is_execute_searching{ false };
    RedMine::Response::UserInfo user_info;
    Listener listener;

    RedMineData() : listener(App->Bus())
    {
        AsyncGetUserInfo();
        listener.listen<AppEvent::AppConfigEvent>([this](const auto&)
            {
                AsyncGetUserInfo();
            });
    }

    ~RedMineData()
    {
        listener.unlistenAll();
    }

    void AsyncGetUserInfo()
    {
        App->Async([this]() { user_info = RedMine::GetCurrentUserInfo(); });
    }
};

static void RenderIssueTable(std::vector<RedMineIssue>& issues, bool* reload)
{
    if (ImGui::BeginTable("##SearchResultTable", 5,
        ImGuiTableFlags_Borders |
        ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit))
    {
        ImGui::TableSetupColumn("问题ID");
        ImGui::TableSetupColumn("问题描述", ImGuiTableColumnFlags_WidthStretch);
        ImGui::TableSetupColumn("所属项目", ImGuiTableColumnFlags_WidthStretch);
        ImGui::TableSetupColumn("分派给");
        ImGui::TableSetupColumn("操作");
        ImGui::TableSetupScrollFreeze (1, 1);  // pin header row
        ImGui::TableHeadersRow();

        for (auto const& x : issues)
        {
            ImGui::PushID(&x);

            if (x.is_closed)
            {
                ImGui::PushStyleColor (ImGuiCol_Text, IM_COL32 (255, 255, 25, 255));
            }

            ImGui::TableNextRow();
            ImGui::TableNextColumn();
            ImGui::Text("#%-5d", x.issue_id);
            ImGui::TableNextColumn();
            ImGui::TextUnformatted(x.issue_name.c_str());
            ImGui::TableNextColumn();
            ImGui::TextUnformatted(x.project_name.c_str());
            ImGui::TableNextColumn();

            if (x.is_closed)
            {
                ImGui::PopStyleColor (1);
            }

            ImGui::TextUnformatted (x.assigned_to.c_str ());
            ImGui::TableNextColumn ();
            
            // 关闭/打开问题操作
            const char *btn_text = x.is_closed ? ICON_FA_UPLOAD " 重新打开" : ICON_FA_DOWNLOAD " 关闭问题";

            if (ImGui::SmallButton(btn_text))
            {
                App->Async ([x, reload] () { 
                    auto copy = x;
                    copy.is_closed ^= true;
                    (void)App->Sql ()->UpdateRedMineIssue (copy);
                    if (reload)
                    {
                        *reload = true;
                    }
                    App->Bus ()->postpone (AppEvent::IssueEvent {});
                });
            }

            ImGui::SameLine ();
            if (ImGui::SmallButton(ICON_FA_TIMES " 删除"))
            {
                App->Async([x, reload]()
                    {
                        (void)App->Sql()->DeleteRedMineIssue(x.issue_id);
                        if (reload) {
                            *reload = true;
                        }
                        App->Bus()->postpone(AppEvent::IssueEvent{});
                    });
            }
            ImGui::PopID();
        }
        ImGui::EndTable();
    }
}

RedMineToolsView::RedMineToolsView() : d{ new RedMineData }
{
}

RedMineToolsView::~RedMineToolsView()
{
    delete d;
}

unsigned int RedMineToolsView::Flags() const
{
    return eTab | eDialog;
}

void RedMineToolsView::RenderContent(ComponentFlag flag)
{
    if (flag == eTab)
        Tab();
    else if (flag == eDialog)
        Dialog();
}

const char* RedMineToolsView::GetName(ComponentFlag flag)
{
    if (flag == eTab)
        return TAB_NAME_OF(AppEvent::SelectTabEvent::eRedMine);
    else if (flag == eDialog)
        return MODAL_DIALOG_NAME(REDMINE_MANAGEMENT_DIALOG_NAME);
    return nullptr;
}

void RedMineToolsView::Tab()
{
    if (d->reload_activities)
    {
        d->reload_activities = false;
        d->activities = App->Sql()->AllRedMineActivities();
    }

    if (d->reload_issues)
    {
        d->reload_issues = false;
        d->imported_issues = App->Sql()->AllRedMineIssues();
    }

    if (ImGui::CollapsingHeader("RedMine 账号信息", ImGuiTreeNodeFlags_DefaultOpen) && d->user_info.id > 0)
    {
        ImGui::BulletText("用户ID：%d", d->user_info.id);
        ImGui::BulletText("登录名：%s", d->user_info.login.c_str());
        ImGui::BulletText("用户名：%s %s", d->user_info.lastname.c_str(), d->user_info.firstname.c_str());
        ImGui::BulletText("邮  箱：%s", d->user_info.mail.c_str());
    }
    else if (d->user_info.id <= 0)
    {
        ImGui::TextUnformatted("请先检查RedMine配置和网络连接情况！！");
        ImGui::SameLine();
        if (ImGui::Button(ICON_FA_REFRESH))
        {
            d->AsyncGetUserInfo();
        }
        return;
    }

    if (ImGui::CollapsingHeader("RedMine 活动列表", ImGuiTreeNodeFlags_DefaultOpen))
    {
        for (auto const& x : d->activities)
        {
            ImGui::BulletText("#%-3d %s", x.act_id, x.act_name.c_str());
        }

        ImGui::Spacing();
        if (ImGui::Button("与服务器同步 " ICON_FA_REFRESH))
        {
            App->Async([&first = d->reload_activities]() mutable
            {
                auto activities = RedMine::GetRedMineActivities();
                for (auto& x : activities)
                {
                    auto sql = App->Sql();
                    auto act = RedMineActivity{ x.id, x.name };
                    sql->UpdateRedMineActivity(act);
                }
                first = true;
                App->Bus()->postpone(AppEvent::ActivityEvent{});
            });
        }
        HelperMaker("点击从RedMine服务器上查询所以可选活动，并更新数据库中的记录。", true);
    }

    if (ImGui::CollapsingHeader("RedMine 问题列表", ImGuiTreeNodeFlags_DefaultOpen))
    {
        if (ImGui::Button("管理问题 " ICON_FA_PENCIL_SQUARE))
        {
            App->ShowDialog(REDMINE_MANAGEMENT_DIALOG_NAME);
        }

        if (d->imported_issues.empty())
        {
            ImGui::BulletText("还没有导入任何问题。");
        }
        else
        {
            RenderIssueTable(d->imported_issues, &d->reload_issues);
        }
    }
}

void RedMineToolsView::Dialog()
{
    // data init
    if (d->dialog_first_frame)
    {
        d->dialog_first_frame = false;
        d->page = 0;
        d->total_result = 0;
    }
    static const char* texts[RedMine::SFT_CNT]{ "标题描述（模糊匹配，有些情况下搜索不到）","问题编号（多问题支持英文逗号','分隔）" };
    const auto do_search = [&]()
    {
        d->is_execute_searching = true;
        App->Async([this]
            {
                auto ret = RedMine::SearchRedMineIssue(d->search_type, d->search_key_word, d->filter_assigned_to_me, d->filter_open_only, d->page_size, d->page,
                    &d->total_result);
                std::unique_lock lck(d->result_rw_lock);
                d->result_issues.clear();
                d->result_issues.reserve(ret.size());
                for (auto& r : ret)
                {
                    RedMineIssue issue;
                    issue.issue_id = r.id;
                    issue.assigned_to = r.assigned_to.name;
                    issue.is_closed = r.status.name == "已关闭";
                    issue.project_name = r.project.name;
                    issue.issue_name = r.subject;
                    d->result_issues.emplace_back(std::move(issue));
                }
                d->is_execute_searching = false;
            });
    };
    ImGui::BeginDisabled(d->is_execute_searching);
    if (ImGui::BeginCombo("筛选方式", texts[d->search_type]))
    {
        for (int i = 0; i < RedMine::SFT_CNT; ++i)
        {
            const bool is_selected = i == d->search_type;
            if (ImGui::Selectable(texts[i])) {
                d->search_type = i;
                d->search_key_word = "";
            }
            if (is_selected)
                ImGui::SetItemDefaultFocus();
        }
        ImGui::EndCombo();
    }
    if (ImGui::InputTextWithHint("##Keyword", "键入搜索关键字...", &d->search_key_word))
    {
        d->page = 0;

        // do_search();
    }
    if (ImGui::Checkbox("仅分配给我的问题", &d->filter_assigned_to_me))
    {
        d->page = 0;

        // do_search();
    }
    HelperMaker("选中以筛选指派给\"我\"的问题。", true);
    ImGui::SameLine();
    if (ImGui::Checkbox("仅限打开的问题", &d->filter_open_only))
    {
        d->page = 0;
    }
    HelperMaker("选中以筛选状态为\"已打开\"的问题。", true);
    if (ImGui::Button(ICON_FA_SEARCH " 搜索"))
    {
        do_search();
    }
    ImGui::SameLine();
    if (ImGui::Button(ICON_FA_STEP_BACKWARD " 首页") && d->page > 0)
    {
        d->page = 0;
        do_search();
    }
    ImGui::SameLine();
    if (ImGui::Button(ICON_FA_ARROW_LEFT " 上一页") && d->page > 0)
    {
        --d->page;
        do_search();
    }
    ImGui::SameLine();
    if (ImGui::Button(ICON_FA_ARROW_RIGHT " 下一页") && (d->page + 1) * d->page_size < d->total_result)
    {
        ++d->page;
        do_search();
    }
    ImGui::SameLine();
    if (ImGui::Button(ICON_FA_STEP_FORWARD " 尾页") && (d->page + 1) * d->page_size < d->total_result)
    {
        d->page = (d->total_result - 1) / d->page_size;
        do_search();
    }
    ImGui::EndDisabled();

    // display some info
    ImGui::Text("展示第%d至%d项，共%d项", std::min<int>(d->page * d->page_size + 1, d->total_result),
        std::min<int>(d->page_size * (d->page + 1), d->total_result), d->total_result);

    // result table
    std::shared_lock lck(d->result_rw_lock);
    if (d->is_execute_searching)
    {
        ImGui::Text(ICON_FA_REFRESH " 正在加载。。。");
    }
    else if (ImGui::BeginTable("##SearchResultTable", 5,
        ImGuiTableFlags_Borders |
        ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit))
    {
        ImGui::TableSetupColumn("问题ID");
        ImGui::TableSetupColumn("问题描述", ImGuiTableColumnFlags_WidthStretch);
        ImGui::TableSetupColumn("所属项目", ImGuiTableColumnFlags_WidthStretch);
        ImGui::TableSetupColumn("分派给");
        ImGui::TableSetupColumn("操作");
        ImGui::TableSetupScrollFreeze (1, 1);
        ImGui::TableHeadersRow();

        for (auto const& x : d->result_issues)
        {
            ImGui::PushID(&x);
            ImGui::TableNextRow();
            ImGui::TableNextColumn();
            ImGui::Text("#%-5d", x.issue_id);
            ImGui::TableNextColumn();
            ImGui::TextUnformatted(x.issue_name.c_str());
            ImGui::TableNextColumn();
            ImGui::TextUnformatted(x.project_name.c_str());
            ImGui::TableNextColumn();
            ImGui::TextUnformatted(x.assigned_to.c_str());
            ImGui::TableNextColumn();
            if (ImGui::SmallButton(ICON_FA_PLUS " 导入"))
            {
                App->Async([x, reload = &d->reload_issues]()
                {
                    auto copy = x;
                    if (App->Sql()->UpdateRedMineIssue(copy))
                    {
                        *reload = true;
                        App->Bus()->postpone(AppEvent::IssueEvent{});
                    }
                });
            }
            ImGui::PopID();
        }
        ImGui::EndTable();
    }
    // ImGui::SetCursorPosY(ImGui::GetWindowContentRegionMax().y - ImGui::GetTextLineHeight() * 1.5f);
    // if (ImGui::Button(ICON_FA_TIMES " 关闭"))
    //     ImGui::CloseCurrentPopup();
    ImGui::WindowBottomButtons(1, default_ok_cancel_button_text, [](int,void*){
        ImGui::CloseCurrentPopup();
    }, nullptr);
}
